package snapex.core.security;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.util.Base64Utils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import lombok.extern.slf4j.Slf4j;
import snapex.core.model.MyOAuth2AccessToken;
import snapex.core.model.User;
import snapex.user.service.IUserService;

@Slf4j
@Configuration
public class GatewayTokenServiceProxyConfiguration {

	@Value("${snapex.wechat.clientId}")
	String wechatClientId;
	
	@Value("${snapex.wechat.clientSecret}")
	String wechatClientSecret;
		
	@Value("${snapex.wechat.accessTokenUrl}")
	String wechatAccessTokenUrl;
	
	@Bean
	public GatewayTokenServiceProxy gatewayTokenServiceProxy(RestTemplate restTemplate, IUserService userService) {
		
		return new GatewayTokenServiceProxy() {
			@Override
			public MyOAuth2AccessToken getAccessTokenByOpenId(String openId) {
				User user = userService.getByOpenId(openId);
				if(user != null) {
					return this.getAccessToken(user.getUserId(), user.getPassword().replace("{noop}", ""),false);
				}				
				return null;
			}
			
			@Override
			public MyOAuth2AccessToken getAccessToken(String userId, String password, boolean isPasscode) {
				
				if(isPasscode) {
					password = userService.getByUserId(userId).getPassword().replace("{noop}", "");
				}
				
				HttpHeaders requestHeaders = new HttpHeaders();
				requestHeaders.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString((wechatClientId+":"+wechatClientSecret).getBytes()));
				
				HttpEntity requestEntity = new HttpEntity(null, requestHeaders);
				try {
					//accessTokenUrl: http://localhost:${server.port}/oauth/token?grant_type=password&scope=openid&username=%s&password=%s
					return restTemplate.postForObject(String.format(wechatAccessTokenUrl,userId,password), requestEntity,  MyOAuth2AccessToken.class);
				}catch(RestClientException e) {
					log.error("***Failed to getAccessToken for user:{}",userId);					
				}
				return null;
			}

			@Override
			public MyOAuth2AccessToken getAccessTokenByHashKey(String hashKey) {
				
				User user = userService.getByHashKey(hashKey);
				
				return this.getAccessToken(user.getUserId(), user.getPassword().replace("{noop}", ""),false);				
			}
		};
	}
}
